package us.cirion.adventure.ui.mobile;

import javax.microedition.lcdui.Font;

/**
 * MultiLineText is a utility class that supports the concept of text that wraps
 * to multiple lines. The user must provide a limit to the line width. By
 * invoking the next function, the user will be able to determine where each
 * line break should occur. Lines will break at the last whole word that does
 * not extend beyond the width boundary; if a single word is longer than the
 * width, as many characters as fit will be returned.
 * 
 * @author Chris
 */
class MultiLineText
{
	private Font font;
	private int width;
	private String text;
	private int position;

	public MultiLineText(Font font, String txt, int width)
	{
		this.font = font;
		this.text = txt;
		this.width = width;
	}

	public int next()
	{
		int i = position;
		int length = text.length();
		if (position >= length)
			return -1; // No more text to display.
		int start = position;
		while (true)
		{
			// Keep looping until we reach a space or other non-alpha character.
			// (Could enhance to include all whitespace, but game files
			// currently use spaces exclusively; formatting
			// options don't work well in an a generic text environment.)
			while (i < length && text.charAt(i) > ' ')
				i++;
			int w = font.stringWidth(text.substring(start, i));
			if (position == start)
			{
				// If this is the first word on the line, and it's too long to
				// fit, go back
				// and determine how many characters in the word can fit.
				if (w > width)
				{
					while (font.stringWidth(text.substring(start, --i)) > width)
					{
						// Looping over i.
					}
					// Back up one character because it will be incremented in
					// the return.
					position = i - 1;
					break;
				}
			}
			// Keep track of where we landed so we'll start from the right
			// position the next time "next" is called.
			if (w <= width)
				position = i;
			// We're done with this line if we've reached the physical limit, or
			// if we've exhausted all the characters in the text, or if we're at
			// a newline literal.
			if (w > width || i >= length || text.charAt(i) == '\n')
				break;
			i++;
		}
		// Return the last character to draw. We increment the position to skip
		// over the terminating character, if appropriate.
		return position >= length ? position : ++position;
	}
}